"""
请求API模块
封装固件下载控制器的主要功能，为GUI提供统一的API接口
"""
import serial.tools.list_ports
from typing import List, Tuple, Optional, Callable
from .download_controller import DownloadController
from .transport_interface import UsbCanTransport
from .config import g_config
from app.utils.log_ui import UILog

class RequestApi:
    """请求API类，封装固件下载相关的所有操作"""
    
    def __init__(self):
        """初始化API"""
        self._controller: Optional[DownloadController] = None
        self._transport: Optional[UsbCanTransport] = None
        self._progress_callback: Optional[Callable[[float, str], None]] = None
    
    def set_progress_callback(self, callback: Callable[[float, str], None]) -> None:
        """设置进度回调函数
        
        Args:
            callback: 进度回调函数，参数为(progress: float, message: str)
        """
        self._progress_callback = callback
        if self._controller:
            self._controller.set_progress_callback(callback)
    
    def get_available_com_ports(self) -> Tuple[bool, List[str], str]:
        """获取可用的COM口列表
        
        Returns:
            Tuple[bool, List[str], str]: (成功标志, COM口列表, 消息)
        """
        try:
            ports = [port.device for port in serial.tools.list_ports.comports()]
            if not ports:
                return True, [], "未检测到可用的COM口"
            return True, ports, f"发现{len(ports)}个可用COM口"
        except Exception as e:
            return False, [], f"获取COM口列表失败: {str(e)}"
    
    def get_common_can_ids(self) -> List[str]:
        """获取常用CAN ID列表
        
        Returns:
            List[str]: 常用CAN ID的十进制字符串列表(1-64)
        """
        # 常用的CAN ID，采用十进制表示，范围1-64
        common_ids = [str(i) for i in range(1, 65)]
        return common_ids
    
    def validate_can_id(self, can_id_str: str) -> Tuple[bool, int, str]:
        """验证CAN ID格式并转换为整数
        
        Args:
            can_id_str: CAN ID字符串（支持十进制和十六进制）
            
        Returns:
            Tuple[bool, int, str]: (是否有效, CAN ID整数值, 消息)
        """
        try:
            # 去除空格
            can_id_str = can_id_str.strip()
            
            # 支持十六进制格式（0x开头）
            if can_id_str.lower().startswith('0x'):
                can_id = int(can_id_str, 16)
            else:
                can_id = int(can_id_str)
            
            # 验证CAN ID范围（标准帧：0-0x7FF，扩展帧：0-0x1FFFFFFF）
            if 0 <= can_id <= 0x7FF:
                return True, can_id, "标准CAN ID格式"
            elif 0 <= can_id <= 0x1FFFFFFF:
                return True, can_id, "扩展CAN ID格式"
            else:
                return False, 0, "CAN ID超出有效范围"
                
        except ValueError:
            return False, 0, "无效的CAN ID格式"
    
    def init_connection(self, com_port: str, tx_id: int, rx_id: int, 
                       baudrate: int = 1000000) -> Tuple[bool, str]:
        """初始化连接
        
        Args:
            com_port: COM口名称
            tx_id: 发送CAN ID
            rx_id: 接收CAN ID  
            baudrate: CAN波特率
            
        Returns:
            Tuple[bool, str]: (成功标志, 消息)
        """
        try:
            # 创建传输层
            self._transport = UsbCanTransport("usbcan")
            
            # 创建下载控制器
            self._controller = DownloadController(self._transport)
            
            # 设置进度回调
            if self._progress_callback:
                self._controller.set_progress_callback(self._progress_callback)
            
            # 更新配置
            g_config.update_can_config(tx_id=tx_id, rx_id=rx_id, baudrate=baudrate)
            
            # 初始化系统
            suc, msg = self._controller.init_system(g_config.can)
            if not suc:
                return False, f"初始化系统失败: {msg}"
            
            return True, "连接初始化成功"
            
        except Exception as e:
            return False, f"初始化连接异常: {str(e)}"
    
    def connect_target(self, retry_count: int = 3) -> Tuple[bool, str]:
        """连接目标设备
        
        Args:
            retry_count: 重试次数
            
        Returns:
            Tuple[bool, str]: (成功标志, 消息)
        """
        if not self._controller:
            return False, "控制器未初始化"
        
        return self._controller.connect_target(retry_count)
    
    def disconnect_target(self) -> Tuple[bool, str]:
        """断开目标设备
        
        Returns:
            Tuple[bool, str]: (成功标志, 消息)
        """
        if not self._controller:
            return False, "控制器未初始化"
        
        return self._controller.disconnect_target() 
    
    def load_firmware(self, file_path: str) -> Tuple[bool, str]:
        """加载固件文件
        
        Args:
            file_path: 固件文件路径
            
        Returns:
            Tuple[bool, str]: (成功标志, 消息)
        """
        if not self._controller:
            return False, "控制器未初始化"
        
        return self._controller.load_firmware(file_path)
    
    def download_firmware(self) -> Tuple[bool, str]:
        """下载固件
        
        Returns:
            Tuple[bool, str]: (成功标志, 消息)
        """
        if not self._controller:
            return False, "控制器未初始化"
        
        return self._controller.download_firmware()
    
    def get_firmware_info(self) -> Tuple[bool, dict, str]:
        """获取固件信息
        
        Returns:
            Tuple[bool, dict, str]: (成功标志, 固件信息字典, 消息)
        """
        if not self._controller:
            return False, {}, "控制器未初始化"
        
        return self._controller.get_firmware_info()
    
    def get_download_progress(self) -> float:
        """获取下载进度
        
        Returns:
            float: 下载进度百分比 (0.0-100.0)
        """
        if not self._controller:
            return 0.0
        
        return self._controller.get_download_progress()
    
    def get_actual_com_port(self) -> Tuple[bool, str, str]:
        """获取实际使用的COM口
        
        在连接成功后，可能由于自动识别机制，实际使用的COM口与用户选择的不同
        
        Returns:
            Tuple[bool, str, str]: (成功标志, 实际COM口, 消息)
        """
        if not self._transport:
            return False, "", "传输层未初始化"
        
        try:
            # 获取实际使用的COM口配置
            if hasattr(self._transport, '_device_handle') and self._transport._device_handle:
                device = self._transport._device_handle
                if hasattr(device, '_ser_config') and device._ser_config:
                    actual_port = device._ser_config.port
                    return True, actual_port, f"实际使用COM口: {actual_port}"
            
            return False, "", "无法获取实际COM口信息"
            
        except Exception as e:
            return False, "", f"获取实际COM口异常: {str(e)}"

    def disconnect(self) -> Tuple[bool, str]:
        """断开连接并清理资源
        
        Returns:
            Tuple[bool, str]: (成功标志, 消息)
        """
        if not self._controller:
            return True, "控制器未初始化"
        
        try:
            suc, msg = self._controller.deinit_system()
            self._controller = None
            self._transport = None
            return suc, msg
        except Exception as e:
            return False, f"断开连接异常: {str(e)}"
    
    def is_connected(self) -> bool:
        """检查是否已连接
        
        Returns:
            bool: 连接状态
        """
        if not self._controller:
            return False
        
        return self._controller._xcp.is_connected() if hasattr(self._controller, '_xcp') else False

# 全局API实例
api = RequestApi()